﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Magiq.Support;
using Magiq.Tests.Support;
using NUnit.Framework;

namespace Magiq.Tests
{
    [TestFixture]
    public class ExpressionSplitTests
    {
        private class ModelA
        {
            public ModelB ModelB { get; set; }
        }

        private class ModelB
        {
            public IEnumerable<string> Items { get; set; }
        }

        private readonly ModelA model = new ModelA
                                   {
                                       ModelB = new ModelB
                                                    {
                                                        Items = new List<string>
                                                                    {
                                                                        "aaa",
                                                                        "bbb",
                                                                        "cc"
                                                                    }
                                                    }
                                   };

        [Test]
        public void ShouldSplitJustProperty()
        {
            Expression<Func<ModelB,IEnumerable<string>>> lambda = x => x.Items;
            var split = ExpressionSplit<ModelB, string>.From(lambda);
            split.PropertyExpression.Compile()(model.ModelB).Should(Be.EqualTo(model.ModelB.Items));
            split.WhereExpression.Should(Be.Null);
        }

        [Test]
        public void ShouldSplitPropertyAndWhere()
        {
            Expression<Func<ModelB, IEnumerable<string>>> lambda = x => x.Items.Where(i => i.Length == 3);
            var split = ExpressionSplit<ModelB, string>.From(lambda);
            split.PropertyExpression.Compile()(model.ModelB).Should(Be.EqualTo(model.ModelB.Items));
            split.WhereExpression.Compile()("bla").Should(Be.True);
        }

        [Test]
        public void ShouldSplitJustPropertyChain()
        {
            Expression<Func<ModelA, IEnumerable<string>>> lambda = x => x.ModelB.Items;
            var split = ExpressionSplit<ModelA, string>.From( lambda);
            split.PropertyExpression.Compile()(model).Should(Be.EqualTo(model.ModelB.Items));
            split.WhereExpression.Should(Be.Null);
        }

        [Test]
        public void ShouldSplitPropertyChainAndWhere()
        {
            Expression<Func<ModelA, IEnumerable<string>>> lambda = x => x.ModelB.Items.Where(i => i.Length == 3);
            var split = ExpressionSplit<ModelA, string>.From(lambda);
            split.PropertyExpression.Compile()(model).Should(Be.EqualTo(model.ModelB.Items));
            split.WhereExpression.Compile()("bla").Should(Be.True);
        }
    }
}